package com.hd123.rumba.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.hd123.rumba.request.JspLib;
import com.hd123.rumba.runtime.FormatSettings;

/**
 * @author caili
 */
public class FileUtils {

  public static void main2(String[] args) throws Exception {
    List files = FileUtils.listFiles(new File("c:/temp/model/tango/com/hd123/rumba"),
        javaFileFilter, true);
    for (int i = 0; i < files.size(); ++i) {
      System.out.println(((File) files.get(i)).getAbsoluteFile());
    }
  }

  public static FilenameFilter javaFileFilter = new FilenameFilter() {
    public boolean accept(File dir, String name) {
      return name.endsWith(".java");
    }
  };

  public static FilenameFilter dirFilter = new FilenameFilter() {
    public boolean accept(File dir, String name) {
      return new File(dir, name).isDirectory();
    }
  };

  public static FilenameFilter dirHasJavaFilesFilter = new FilenameFilter() {
    public boolean accept(File dir, String name) {
      File file = new File(dir, name);
      if (file.isDirectory()) {
        File[] files = file.listFiles(javaFileFilter);
        return files != null && files.length > 0;
      }
      return false;
    }
  };

  /**
   * 搜索file目录下的文件(包括目录), 返回满足filter的文件或目录的列表. 如果file是一个文件, 则返回此文件.
   * 
   * @param file
   * @param filter
   *          null表示不过滤
   * @param recursive
   *          是否递归搜索
   * @return List of File
   */
  public static List listFiles(File file, FilenameFilter filter, boolean recursive) {
    List list = new ArrayList();
    if (file.isFile() && (filter == null || filter.accept(file.getParentFile(), file.getName()))) {
      list.add(file);
    } else {
      File[] files = file.listFiles();
      for (int i = 0; files != null && i < files.length; ++i) {
        if (filter == null || filter.accept(files[i].getParentFile(), files[i].getName()))
          list.add(files[i]);
        if (recursive && files[i].isDirectory())
          list.addAll(listFiles(files[i], filter, recursive));
      }
    }
    return list;
  }

  /**
   * 删除文件或目录. 如果是目录的话, 递归删除这个目录中所有的文件和目录
   * 
   * @param file
   * @return
   */
  public static boolean deleteFile(File file) {
    if (file.isFile())
      return file.delete();
    else {
      File[] files = file.listFiles();
      for (int i = 0; i < files.length; ++i)
        if (!deleteFile(files[i]))
          return false;
      return file.delete();
    }
  }

  /**
   * 取得目录dir中最新的limit个文件.
   * 
   * @param dir
   * @param limit
   * @param recursive
   *          是否递归包含子目录
   * @return list of File
   */
  public static List getLastestFiles(File dir, FilenameFilter filter, int limit, boolean recursive) {
    List files = listFiles(dir, filter, recursive);
    // 按时间倒序排序文件
    for (int i = 0; i < files.size() - 1; ++i) {
      for (int j = i + 1; j < files.size(); ++j) {
        File a = (File) files.get(i);
        File b = (File) files.get(j);
        if (a.lastModified() < b.lastModified()) {
          files.set(i, b);
          files.set(j, a);
        }
      }
    }
    List result = new ArrayList();
    for (int i = 0; result.size() < limit && i < files.size(); ++i) {
      if (((File) files.get(i)).isFile())
        result.add(files.get(i));
    }
    return result;
  }

  public static List getLastestFiles(File dir, int limit, boolean recursive) {
    return getLastestFiles(dir, null, limit, recursive);
  }

  public static List getLastestFilesExclude(File dir, String[] excludeDirs, int limit,
      boolean recursive) {
    return getLastestFiles(dir, new ExcludeDirFilter(excludeDirs), limit, recursive);
  }

  private static class ExcludeDirFilter implements FilenameFilter {
    private String[] dirs;

    public ExcludeDirFilter(String[] dirs) {
      this.dirs = dirs;
    }

    public boolean accept(File dir, String name) {
      if (dirs == null)
        return true;
      File file = new File(dir, name);
      for (int i = 0; i < dirs.length; ++i)
        if (file.getAbsolutePath().startsWith(dirs[i]))
          return false;
      return true;
    }
  }

  public static byte[] readStreamBytes(InputStream in) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    byte[] b = new byte[128];
    int bytesRead = -1;
    while (-1 != (bytesRead = in.read(b, 0, b.length))) {
      out.write(b, 0, bytesRead);
    }
    out.flush();
    byte[] result = out.toByteArray().clone();
    in.close();
    out.close();
    return result;
  }
  
  public static String readStreamString(InputStream in) throws IOException {
    return new String(readStreamBytes(in));
  }
  
  public static void main(String[] args) throws Exception {
    List files = getLastestFiles(new File("c:/eos/workspace/eos/src/com/hd123/nova"), 30, true);
    for (int i = 0; i < files.size(); ++i) {
      File file = (File) files.get(i);
      System.out.println(JspLib.format(new Date(file.lastModified()), FormatSettings.SDFyMdHms)
          + " " + file.getAbsolutePath());
    }
  }
  
}
